﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZombieMonkeys.Vibria.Logic;
using System.Xml;
using System.Xml.Linq;

namespace ZombieMonkeys.Vibria.DAL
{
    /// <summary>
    /// A class that will save out a current Sudoku Puzzle as an xml file
    /// </summary>
    public class PuzzleSaver
    {
        /// <summary>
        /// private instance of PuzzleSaver, Singleton
        /// </summary>
        static PuzzleSaver instance;
        /// <summary>
        /// private singleton constructor
        /// </summary>
        private PuzzleSaver()
        {

        }

        #region PublicMethods
        public static PuzzleSaver GetPuzzleSaver()
        {
            if (instance == null)
            {
                instance = new PuzzleSaver();
            }
            return instance;
        }
        /// <summary>
        /// Save the puzzle data without any time information
        /// </summary>
        /// <param name="xmlSaveFilePath"></param>
        /// <param name="xmlSaveFileName"></param>
        /// <param name="puzzleToSave"></param>
        public void SavePuzzle(string xmlSaveFilePath, string xmlSaveFileName, Puzzle puzzleToSave)
        {
            XElement puzzleXElementData = createPuzzleXml(puzzleToSave);
            writeItemData(puzzleXElementData, xmlSaveFilePath, xmlSaveFileName);
        }

        /*DO NOT CALL THIS METHOD YET!*/
        /// <summary>
        /// Save the puzzle data with the time information passed in
        /// </summary>
        /// <param name="xmlSaveFilePath"></param>
        /// <param name="xmlSaveFileName"></param>
        /// <param name="puzzleToSave">The puzzle object that you wish to save</param>
        /// <param name="puzzleTimeDataToSave">the current amount of time spent on the puzzle</param>
        public void SavePuzzleComplete(string xmlSaveFilePath, string xmlSaveFileName, Puzzle puzzleToSave, PuzzleTimeData puzzleTimeDataToSave)
        {
            XElement puzzleXElementData = createPuzzleXml(puzzleToSave);
            XElement puzzleXElementTimeData = createTimeDataXml(puzzleTimeDataToSave);
            puzzleXElementData.Add(puzzleXElementTimeData);
            writeCompleteItemData(puzzleXElementData, xmlSaveFilePath, xmlSaveFileName);
        }

        #endregion PublicMethods

        #region privateMethods

        private void writeItemData(XElement puzzleData, string directory, string fileName)
        {
            string filePath = directory + fileName;
            puzzleData.Save(filePath);
        }

        private void writeCompleteItemData(XElement puzzleData, string directory, string fileName)
        {
            //puzzleData.add(timeData)
            string filePath = directory;
            puzzleData.Save(filePath);
        }

        private int getRowCount(Puzzle puzzle)
        {
            int count = 0;
            count = puzzle.Rows;
            return count;
        }

        private int getColCount(Puzzle puzzle)
        {
            int count = 0;
            count = puzzle.Cols;
            return count;
        }

        private int getRowId(Square square)
        {
            int id = square.GetRow();
            return id;
        }

        private XElement createPuzzleXml(Puzzle puzzleToSave)
        {
            XElement squareXElement;
            XElement puzzleXElement = new XElement("puzzle");
            XElement valuesXElement = new XElement("values");
            //add rows attribute, to puzzleXElement
            puzzleXElement.SetAttributeValue("rows", puzzleToSave.Rows);
            puzzleXElement.SetAttributeValue("cols", puzzleToSave.Cols);
            puzzleXElement.SetAttributeValue("diff", puzzleToSave.Difficulty);
            
            int iPermanent = 0;

            foreach (Square square in puzzleToSave.Grid.SquareList)
            {
                //get each squares data
                squareXElement = new XElement("s");
                //set row
                squareXElement.SetAttributeValue("r", square.GetRow());
                //set column
                squareXElement.SetAttributeValue("c", square.GetColumn());
                //square is permanent
                if (square.GetPermanency())
                {
                    iPermanent = 1;
                }
                else //square is not permanent
                {
                    iPermanent = 0;
                }
                squareXElement.SetAttributeValue("p", iPermanent);
                squareXElement.SetAttributeValue("v", square.Value);
                squareXElement.SetAttributeValue("n1", square.GetNoteValue(0));
                squareXElement.SetAttributeValue("n2", square.GetNoteValue(1));
                squareXElement.SetAttributeValue("n3", square.GetNoteValue(2));
                squareXElement.SetAttributeValue("n4", square.GetNoteValue(3));
                valuesXElement.Add(squareXElement);

            }

            //add values
            puzzleXElement.Add(valuesXElement);
            return puzzleXElement;
        }

        //seprate logic for creating time information from a puzzle, 
        private XElement createTimeDataXml(PuzzleTimeData puzzleTimeData)
        {
            XElement timeDataXElement = new XElement("ct");
            //set up the logic to get all the information from the PuzzleTimeData
            //and return the information as xml
            return timeDataXElement;
        }

        #endregion privateMethods
    }
}
